// cifrario di vigenere, su file di testo, versione 2, restaurata
// author: N0R81X
// MSN: bobcat01@hotmail.com (no mail)
// eMail: xibron[at]gmail[dot]com (no spam!)
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>
void anim(char *text);
char rotate_left(char c);
char rotate_right(char c);
char rotate(char c, int n, char direction);
char *vigenere_enc(char *plaintext, char *pass);
char *vigenere_dec(char *ciphertext, char *pass);
char *get_worm(long lenght, char *pass);
long get_file_size(char *fname);
char *read_file(char *fname);
short write_file(char *fname, char *data);
void str_to_upper(char *str);
char *get_password(long max_lenght);
int char_check(char *pass);
int lenght_check(char *pass, long max_lenght);
void clear(void);
void gotoXY(int x, int y);
int main()
{
char *plaintext, *ciphertext;
char fname[1024], *pass, temp[1024];
char choice;
long lenght;
while(1)
{
clear();
anim("\n\n ~ Cifrario di Vigenere v2 by N0R81X ~ \n\n");
anim("1 - Codifica\n");
anim("2 - Decodifica\n");
anim("3 - Esci\n\n");
choice = getch();
if(choice == '1')
{
anim("File di testo da cifrare: ");
fgets(fname, 1024, stdin);
fname[strlen(fname) - 1] = 0;
if((plaintext = read_file(fname)) == NULL)
{
sprintf(temp, "Impossibile leggere %s\n", fname);
anim(temp);
getch();
return 0;
}
lenght = get_file_size(fname);
printf("Lunghezza testo: %d byte\n", lenght);
pass = get_password(lenght);
if(pass == NULL)
{
anim("Errore nella lettura della password\n");
getch();
return 0;
}
ciphertext = (char *)malloc(lenght + 1);
if(ciphertext == NULL) return 0;
ciphertext[lenght + 1] = 0;
ciphertext = vigenere_enc(plaintext, pass);
if((write_file(fname, ciphertext)) == 0)
{
sprintf(temp, "Impossibile scrivere %s\n", temp);
anim(temp);
getch();
return 0;
}
free(plaintext);
free(ciphertext);
anim("File cifrato!\n");
}
else if(choice == '2')
{
anim("File di testo da decifrare: ");
fgets(fname, 1024, stdin);
fname[strlen(fname) - 1] = 0;
if((ciphertext = read_file(fname)) == NULL)
{
sprintf(temp, "Impossibile leggere %s\n", fname);
anim(temp);
getch();
return 0;
}
lenght = get_file_size(fname);
printf("Lunghezza testo: %d byte\n", lenght);
pass = get_password(lenght);
plaintext = (char *)malloc(lenght);
if(plaintext == NULL) return 0;
plaintext = vigenere_dec(ciphertext, pass);
if((write_file(fname, plaintext)) == 0)
{
sprintf(temp, "Impossibile scrivere %s\n", temp);
anim(temp);
getch();
return 0;
}
free(plaintext);
free(ciphertext);
anim("File decifrato!\n");
}
else if(choice == '3') return 0;
else if(choice < '1' || choice > '2')
{
sprintf(temp, "Scelta 1, 2 o 3, nessuna scelta %c!\n", choice);
anim(temp);
}
getch();
}
}
void anim(char *text)
{
int i;
for(i = 0; i <= strlen(text); i++)
{
printf("%c", text[i]);
if((text[i] != ' ') || (text[i] != '\n')) _sleep(15);
}
}
char rotate_left(char c)
{
if(c >= 'A' && c <= 'Z')
{
if(c == 'A') c = 'Z';
else c--;
}
else if(c >= 'a' && c <= 'z')
{
if(c == 'a') c = 'z';
else c--;
}
else if(c >= '0' && c <= '9')
{
if(c == '0') c = '9';
else c--;
}
return c;
}
char rotate_right(char c)
{
if(c >= 'A' && c <= 'Z')
{
if(c == 'Z') c = 'A';
else c++;
}
if(c >= 'a' && c <= 'z')
{
if(c == 'z') c = 'a';
else c++;
}
else if(c >= '0' && c <= '9')
{
if(c == '9') c = '0';
else c++;
}
return c;
}
char rotate(char c, int n, char direction)
{
int i;
if(direction == 'L')
{
for(i = 0; i < n; i++) c = rotate_left(c);
}
else if(direction == 'R')
{
for(i = 0; i < n; i++) c = rotate_right(c);
}
return c;
}
char *vigenere_enc(char *plaintext, char *pass) // la password deve essere passata alla funzione in caratteri maiuscoli
{
long i, lenght = strlen(plaintext);
char *worm = get_worm(lenght, pass);
char *ciphertext = (char *)malloc(lenght);
if(ciphertext == NULL) return NULL;
for(i = 0; i <= lenght; i++)
{
ciphertext[i] = rotate(plaintext[i], worm[i] - 'A', 'R');
}
return ciphertext;
}
char *vigenere_dec(char *ciphertext, char *pass) // la password deve essere passata alla funzione in caratteri maiuscoli
{
long i, lenght = strlen(ciphertext);
char *worm = get_worm(lenght, pass);
char *plaintext = (char *)malloc(lenght+1);
if(plaintext == NULL) return NULL;
for(i = 0; i <= lenght; i++)
{
plaintext[i] = rotate(ciphertext[i], worm[i] - 'A', 'L');
}
return plaintext;
}
char *get_worm(long lenght, char *pass)
{
char *worm;
long i;
int pass_len = strlen(pass);
if((worm = (char *)malloc(lenght)) == NULL) return NULL;
memset(worm, 0, lenght);
for(i = 0; i < lenght / pass_len; i++)
{
strcat(worm, pass);
}
for(i = 0; i < lenght % pass_len; i++)
{
strncat(worm, pass, lenght % pass_len);
}
return worm;
}
long get_file_size(char *fname) // ritorna -1 se è impossibile aprire il file
{
FILE *f;
long size;
if((f = fopen(fname, "r")) == NULL) return -1;
fseek(f, 0, SEEK_END);
size = ftell(f);
fclose(f);
return size;
}
char *read_file(char *fname) // ritorna NULL se c'è un errore, altrimenti ritorna i dati letti
{
FILE *f;
long size;
char *data;
size = get_file_size(fname);
if(size == -1) return NULL;
else if((data = (char *)malloc(size)) == NULL) return NULL;
data[size] = 0;
long k;
f = fopen(fname, "r");
if((k = fread(data, 1, size, f)) != size)
{
fclose(f);
printf("ciao, errore lettura.. letti solo %d byte\n", k);
//return NULL;
}
fclose(f);
return data;
}
/*char *read_file(char *fname) // ritorna NULL se c'è un errore, altrimenti ritorna i dati letti
{
FILE *f;
long size, i;
char *data;
size = get_file_size(fname);
if(size == -1) return NULL;
else if((data = (char *)malloc(size)) == NULL) return NULL;
memset(data, 0, size);
f = fopen(fname, "r");
for(i = 0; i <= size; i++) data[i] = getc(f);
fclose(f);
return data;
}*/
short write_file(char *fname, char *data) // se fallisce ritorna 0, altrimenti 1
{
FILE *f;
long size;
size = strlen(data);
if((f = fopen(fname, "w")) == NULL) return 0;
else if(fwrite(data, 1, size, f) != size) return 0;
fclose(f);
return 1;
}
void str_to_upper(char *str)
{
int i;
for(i = 0; i <= strlen(str); i++)
{
if(str[i] >= 'a' && str[i] <= 'z') str[i] = str[i] - 32;
}
}
char *get_password(long max_lenght)
{
char *pass = (char *)malloc(1024);
if(pass == NULL) return NULL;
while(1)
{
anim("Password (case insensitive): ");
fgets(pass, 1024, stdin);
pass[strlen(pass) - 1] = 0;
str_to_upper(pass);
if(char_check(pass) && lenght_check(pass, max_lenght))
{
break;
}
}
return pass;
}
int char_check(char *pass) // controlla che nella password non ci siano numeri
{
int i, j, flag;
char allowed_chars[1024] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for(i = 0; i <= strlen(pass); i++)
{
flag = 0;
for(j = 0; j <= strlen(allowed_chars); j++)
{
if(pass[i] == allowed_chars[j]) flag = 1;
}
if(flag != 1)
{
anim("La password deve contenere solamente lettere, ed e' case insensitive!\n\n");
return 0;
}
}
return 1;
}
int lenght_check(char *pass, long max_lenght) // controlla che la lunghezza della password non superi quella del testo
{
if(strlen(pass) > max_lenght)
{
anim("La password non puo' essere piu' lunga del testo da cifrare!\n\n");
return 0;
}
else return 1;
}
void clear(void)
{
int x, y;
char *row;
CONSOLE_SCREEN_BUFFER_INFO c_info;
HANDLE h_stdout;
h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(h_stdout, &c_info);
// printf("Screen size: %dx%d\n", c_info.dwSize.X, c_info.dwSize.Y);
// printf("Screen size MAX: %dx%d\n", c_info.dwMaximumWindowSize.X, c_info.dwMaximumWindowSize.Y);
// printf("Cursor position: %d, %d\n", c_info.dwCursorPosition.X, c_info.dwCursorPosition.Y);
// printf("Boh: left: %d, right: %d, top: %d, bottom: %d\n", c_info.srWindow.Left, c_info.srWindow.Right, c_info.srWindow.Top, c_info.srWindow.Bottom);
// getchar();
// posiziono il cursore sull'angolo nord ovest della console
gotoXY(0, 0);
// alloco uno spazio equivalente al prodotto di righe e colonne della console
row = (char *)malloc((c_info.srWindow.Right + 1) * (c_info.srWindow.Bottom + 1));
// riempio la stringa ottenuta con spazi bianchi
memset(row, ' ', (c_info.srWindow.Right + 1) * (c_info.srWindow.Bottom + 1));
// pulisco lo schermo inserendo spazi bianchi dappertutto
puts(row);
// libero la memoria precedentemente allocata
free(row);
// riposiziono il cursore sull'angolo nord ovest della console
gotoXY(0, 0);
}
void gotoXY(int x, int y)
{
HANDLE h_stdout;
COORD coord;
coord.X = x;
coord.Y = y;
h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(h_stdout, coord);
}